package com.example.utils;

import java.util.*;
import java.util.stream.Collectors;

public class ObjectComparator {
    public static List<String> getDifferentProperties(
        Map<String, Object> map1,
        Map<String, Object> map2,
        String... ignoredProperties) {

        // 处理空指针情况
        map1 = map1 != null ? map1 : new HashMap<>();
        map2 = map2 != null ? map2 : new HashMap<>();

        // 转换忽略属性为Set
        Set<String> ignored = Arrays.stream(ignoredProperties)
            .collect(Collectors.toSet());

        // 合并所有属性键
        Set<String> allKeys = new HashSet<>();
        allKeys.addAll(map1.keySet());
        allKeys.addAll(map2.keySet());

        Map<String, Object> finalMap = map1;
        Map<String, Object> finalMap1 = map2;
        return allKeys.stream()
            .filter(key -> !ignored.contains(key))
            .filter(key -> {
                boolean has1 = finalMap.containsKey(key);
                boolean has2 = finalMap1.containsKey(key);

                // 存在性不同
                if (has1 != has2) return true;

                // 值不同（使用Objects.equals处理null值）
                return !Objects.equals(finalMap.get(key), finalMap1.get(key));
            })
            .collect(Collectors.toList());
    }

    // 重载方法：支持Set作为忽略参数
    public static List<String> getDifferentProperties(
        Map<String, Object> map1,
        Map<String, Object> map2,
        Set<String> ignoredProperties) {

        return getDifferentProperties(map1, map2,
            ignoredProperties.toArray(new String[0]));
    }

    public static void main(String[] args) {
        Map<String, Object> objA = new HashMap<>();
        objA.put("name", "Alice");
        objA.put("age", 30);
        objA.put("role", "admin");

        Map<String, Object> objB = new HashMap<>();
        objB.put("name", "Bob");
        objB.put("age", 30);
        objB.put("department", "IT");

        // 不忽略任何属性
        System.out.println(getDifferentPropertiesV2(objA, objB));
        // 输出: [department, name, role]

        // 忽略单个属性（数组形式）
        System.out.println(getDifferentPropertiesV2(objA, objB, "department"));
        // 输出: [name, role]

        // 忽略多个属性（Set形式）
        System.out.println(getDifferentPropertiesV2(objA, objB, Set.of("role", "department")));
        // 输出: [name]
    }


    public static List<String> getDifferentPropertiesV2(
        Map<String, Object> map1,
        Map<String, Object> map2,
        String... ignoredProperties) {

        map1 = map1 != null ? map1 : new HashMap<>();
        map2 = map2 != null ? map2 : new HashMap<>();
        Set<String> ignored = new HashSet<>(Arrays.asList(ignoredProperties));
        Set<String> allKeys = new HashSet<>();
        allKeys.addAll(map1.keySet());
        allKeys.addAll(map2.keySet());

        List<String> differences = new ArrayList<>();
        for (String key : allKeys) {
            if (ignored.contains(key)) continue;
            boolean has1 = map1.containsKey(key);
            boolean has2 = map2.containsKey(key);
            if (has1 != has2) {
                differences.add(key);
                continue;
            }
            if (!Objects.equals(map1.get(key), map2.get(key))) {
                differences.add(key);
            }
        }
        return differences;
    }

    public static List<String> getDifferentPropertiesV2(
        Map<String, Object> map1,
        Map<String, Object> map2,
        Set<String> ignoredProperties) {

        return getDifferentPropertiesV2(map1, map2,
            ignoredProperties.toArray(new String[0]));
    }

    public static String appendStr(String str1, String str2) {
        return str1 + str2;
    }
}